package com.flyme.module.base.provider.api;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.flyme.common.core.model.ResultBody;
import com.flyme.common.core.model.query.CriteriaQuery;
import com.flyme.common.core.model.query.PagerInfo;
import com.flyme.common.core.model.query.PqGrid;
import com.flyme.common.core.security.OpenHelper;
import com.flyme.common.core.security.OpenUserAuth;
import com.flyme.common.core.utils.ApiAssert;
import com.flyme.common.core.utils.ObjectUtils;
import com.flyme.core.base.supper.controller.BaseController;
import com.flyme.core.base.supper.entity.EntityMap;
import com.flyme.module.base.client.entity.*;
import com.flyme.module.base.provider.nuonuo.GetInvoice;
import com.flyme.module.base.provider.service.*;
import com.flyme.module.exam.client.entity.BusAbility;
import com.flyme.module.exam.provider.service.BusAbiltityService;
import com.flyme.module.file.client.entity.SysCourse;
import com.flyme.module.file.client.entity.SysLive;
import com.flyme.module.file.client.entity.SysOffCourse;
import com.flyme.module.file.provider.service.SysCourseService;
import com.flyme.module.file.provider.service.SysLiveService;
import com.flyme.module.file.provider.service.SysOffCourseService;
import com.flyme.module.order.client.entity.Order;
import com.flyme.module.order.client.entity.OrderInfo;
import com.flyme.module.order.client.entity.PayBeforeHandler;
import com.flyme.module.order.client.enums.OrderStatusEnum;
import com.flyme.module.order.client.enums.OrderTypeEnum;
import com.flyme.module.order.client.enums.PayStatusEnum;
import com.flyme.module.order.client.enums.PayTypeEnum;
import com.flyme.module.order.provider.service.OrderService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * @author flyme
 */
@Slf4j
@Api(tags = "app订单管理")
@RestController
@RequestMapping("/order")
public class ApiOrderController extends BaseController<OrderService, Order> {

    @Resource
    private AutowireCapableBeanFactory spring;
    @Autowired
    private SysInvoiceService invoiceService;
    @Autowired
    private SysBalanceService balanceService;
    @Autowired
    private SysCourseService sysCourseService;
    @Autowired
    private SysLecturerService lecturerService;
    @Autowired
    private BusAbiltityService abilityService;
    @Autowired
    private SysLiveService liveService;
    @Autowired
    private SysVipTypeService vipTypeService;
    @Autowired
    private SysOffCourseService offcourseService;
    @Autowired
    private SysConfigService sysconfigService;
    @Autowired
    private SysVipPriceService vipPriceService;
    @Autowired
    private SysChargeconfigService chargeconfigService;
    @Autowired
    private SysMessageSendService messageSendService;
    @Autowired
    private SysUserexaminationService sysUserexaminationService;
    @Autowired
    private SysExatimeService sysExatimeService;

    @PostMapping("/addOrder")
    public ResultBody addOrder(HttpServletRequest request, OrderInfo orderInfo, String type) {
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        orderInfo.setHandlerName(type);
        String handlerName = orderInfo.getHandlerName();
        ApiAssert.notNull("参数不能为空", handlerName);
        PayBeforeHandler payBeforeHandler = spring.getBean(OrderTypeEnum.getName(handlerName) + "PayHandler", PayBeforeHandler.class);
        orderInfo.setUserId(openUserAuth.getUserId());
        return payBeforeHandler.addOrder(request, orderInfo);
    }


    /**
     * 查询用户订单
     */
    @PostMapping(value = "/orderList")
    public ResultBody orderList(@ModelAttribute(value = "pagerInfo") PagerInfo pagerInfo, Order order) {
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        CriteriaQuery cq = new CriteriaQuery<EntityMap>(pagerInfo);
        EntityMap.setEnumConvertInterceptor(order);
        cq.select("o.id orderId,o.orderAmount,o.payType,o.orderBody courseTitle,o.orderImage courseImage," +
            "o.isInvoice,o.orderNo,o.orderStatus,o.createTime,o.payStatus,o.targetId,o.orderEntity,o.applyType," +
            "case when o.orderEntity = 'OT_TOP' then chargeconfig.iosId when o.orderEntity = 'OT_VIP' then vipprice.iosId else '0' end iosId");
        cq.eq("userId", openUserAuth.getUserId());
        if (ObjectUtils.isNotEmpty(order.getOrderStatus())) {
            cq.eq("orderStatus", order.getOrderStatus().code);
        }
        cq.eq("isDel", 2);
        cq.orderByDesc("o.createTime");
        cq.createAlias("vipprice", "vipprice");
        cq.createAlias("chargeconfig", "chargeconfig");
        PqGrid pqGrid = bizService.pageList(cq);
        //将用户所有的未读订单消息改为已读
        messageSendService.updateByUser(openUserAuth.getUserId(),2);
        return ResultBody.success(pqGrid);
    }
    /**
     * 查询用户订单
     */
    @PostMapping(value = "/getorderList")
    public ResultBody getorderList(@ModelAttribute(value = "pagerInfo") PagerInfo pagerInfo, Order order) {
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        CriteriaQuery cq = new CriteriaQuery<EntityMap>(pagerInfo);
        EntityMap.setEnumConvertInterceptor(order);
        cq.select("o.id orderId,o.orderAmount,o.payType,o.orderBody examTitle,o.orderImage," +
            "o.isInvoice,o.orderNo,o.orderStatus,o.createTime,o.payStatus,o.targetId,o.orderEntity,o.applyType");
        cq.eq("o.userId", openUserAuth.getUserId());
//        cq.eq("orderEntity",OrderTypeEnum.examnation.code);
        if (ObjectUtils.isNotEmpty(order.getOrderStatus())) {
            cq.eq("orderStatus", order.getOrderStatus().code);
        }
        cq.eq("isDel", 2);
        if(ObjectUtils.isNotEmpty(order.getIsInvoice())){
            cq.eq("o.isInvoice", order.getIsInvoice());
        }
        cq.orderByDesc("o.createTime");
//        cq.createAlias("exam", "exam");
        PqGrid pqGrid = bizService.pageList(cq);
        //将用户所有的未读订单消息改为已读
//        messageSendService.updateByUser(openUserAuth.getUserId(),2);
        return ResultBody.success(pqGrid);
    }


    /**
     * 订单详情
     */
    @PostMapping(value = "/orderDetail")
    public ResultBody orderDetail(String orderId) {
        ApiAssert.notNull("参数不能为空", orderId);
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        EntityMap.setEnumConvertInterceptor(new Order());
        CriteriaQuery cq = new CriteriaQuery();
        cq.select("*");
        cq.eq("id", orderId);
        EntityMap order = bizService.getEntityMap(cq);
        order.put("iosId", "");
        String orderEntity = order.get("orderEntity").toString();
        if (orderEntity.equals(OrderTypeEnum.vip.code)) {
            SysVipPrice vipPrice = vipPriceService.getById(order.get("targetId"));
            order.put("iosId", vipPrice.getIosId());
        }
        if (orderEntity.equals(OrderTypeEnum.top_up.code)) {
            SysChargeconfig chargeconfig = chargeconfigService.getById(order.get("targetId"));
            order.put("iosId", chargeconfig.getIosId());
        }
        //订单状态
        String orderStatus = order.get("orderStatus");
        //支付状态
        String payStatus = order.get("payStatus");
        order.put("countDown", "00:00:00");
        //是否允许删除
        Integer allowDel = 0;
        //是否允许退款
        Integer allowReturn = 0;
        if (OrderStatusEnum.unpaid.code.equals(orderStatus)) {
            order.put("countDown", DateUtil.between(DateUtil.parseDateTime(order.get("closeDate")), DateUtil.date(), DateUnit.SECOND, false));
            allowDel = 1;
        }
        if (OrderStatusEnum.close.code.equals(orderStatus)) {
            allowDel = 1;
        }
        if (payStatus.equals(PayStatusEnum.PAY.code)) {
            if (OrderTypeEnum.offcourse.code.equals(orderEntity) || OrderTypeEnum.live.code.equals(orderEntity)) {
                allowReturn = 1;
            }
        }
        order.put("allowDel", allowDel);
        order.put("allowReturn", allowReturn);
        messageSendService.updateMessage(openUserAuth.getUserId(), orderId);
        return ResultBody.success(order);
    }


    /**
     * 删除订单
     */
    @PostMapping(value = "/delOrder")
    public ResultBody delOrder(String orderId) {
        ApiAssert.notNull("参数不能为空", orderId);
        Order order = bizService.getById(orderId);
        if (order.getOrderStatus().equals(OrderStatusEnum.unpaid)) {
            order.setOrderStatus(OrderStatusEnum.close);
        }
        order.setIsDel(1);
        boolean tag = bizService.saveOrUpdate(order);
        if (tag) {
            if(order.getOrderEntity().equals(OrderTypeEnum.examnation)){
                SysUserexamination sysUserexamination=sysUserexaminationService.getById(order.getTargetId());
                QueryWrapper<SysExatime> qw3 = new QueryWrapper();
                List<SysExatime> extimeList = sysExatimeService.list(qw3.in("id", sysUserexamination.getExatimeId()));
                for(SysExatime exatime : extimeList){
                    if(exatime.getSignlastCount() < 1){
                        continue;
                    }
                    exatime.setSignlastCount(exatime.getSignlastCount() - 1);
                }
                if(extimeList.size() > 0){
                    sysExatimeService.updateBatchById(extimeList);
                    //名额返还后删除考试报名表
                    boolean a=sysUserexaminationService.removeById(order.getTargetId());
                }
            }
            return ResultBody.ok("删除成功");
        }
        return ResultBody.failed("删除失败");
    }
    /**
     * 申请退款
     */
    @PostMapping(value = "/returnAmount")
    public ResultBody returnAmount(Long orderId) {
        ApiAssert.notNull("订单ID不能为空", orderId);
        Order order = bizService.getById(orderId);
        PayStatusEnum payStatusEnum = order.getPayStatus();
        OrderStatusEnum orderStatusEnum = order.getOrderStatus();
        //已支付和已完成的订单允许退款
        if (PayStatusEnum.PAY.equals(payStatusEnum) && OrderStatusEnum.finish.equals(orderStatusEnum)) {
            bizService.updateOrderStatus(orderId, OrderStatusEnum.unretrun);
            return ResultBody.ok("申请成功");
        } else {
            return ResultBody.failed("申请失败");
        }
    }

    /**
     * 我的发票记录
     */
    @PostMapping(value = "/myInvoicePage")
    public ResultBody myInvoicePage(@ModelAttribute(value = "pagerInfo") PagerInfo pagerInfo) {
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        EntityMap map = new EntityMap();
        List<EntityMap> list = invoiceService.selectByUser(String.valueOf(openUserAuth.getUserId()), pagerInfo);
        for(EntityMap invoice : list){
            String createTime = invoice.get("createTime").toString().substring(0,10);
            invoice.put("createTime", createTime);
        }
        map.put("list", list);
        return ResultBody.success(list);
    }


    /**
     * 发票申请页面
     */
    @PostMapping(value = "/applyInvoicePage")
    public ResultBody applyInvoicePage(String orderId) {
        ApiAssert.notNull("参数不能为空", orderId);
        EntityMap map = new EntityMap();
        Order order = bizService.getById(orderId);
        map.put("content", order.getOrderTitle());
        map.put("amount", order.getOrderAmount());
        return ResultBody.success(map);
    }


    /**
     * 支付页面
     */
    @RequestMapping(value = "/buyPage")
    public ResultBody buyPage(Integer type, String targetId, String applyType) {
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        applyType = "1";
        ApiAssert.notNull("参数不能为空", type, targetId);
        EntityMap map = new EntityMap();
        SysBalance balance = balanceService.findByUser(openUserAuth.getUserId());
        map.put("userAmount", balance.getAmount());
        BigDecimal targetAmount = new BigDecimal("0");
        map.put("needRecharge", 2);//不需要充值
        map.put("shortAmount", 0);
        SysConfig config = sysconfigService.getByName("iosRatio");
        BigDecimal iosRatio = new BigDecimal(config.getConfigVal());
        if (type.equals(1)) {//课程购买
            SysCourse course = sysCourseService.getById(targetId);
            SysLecturer lecturer = lecturerService.getById(course.getLecturerId());
            targetAmount = course.getCoursePrice();
            if (applyType.equals(2)) {
                targetAmount = course.getCoursePrice().multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP);
            }
            map.put("img", course.getCourseImage());
            map.put("title", course.getCourseTitle());
            if (ObjectUtils.isNotEmpty(lecturer)) {
                map.put("content", "讲师：" + lecturer.getLecturerName());
            } else {
                map.put("content", "");
            }
            map.put("price", targetAmount);
            map.put("iosPrice", course.getCoursePrice().multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP));
        }
        if (type.equals(2)) {//人才测评购买
            BusAbility ability = abilityService.getById(targetId);
            targetAmount = new BigDecimal(ability.getAbilityPrice());
            if (applyType.equals(2)) {
                targetAmount = new BigDecimal(ability.getAbilityPrice()).multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP);
            }
            map.put("img", ability.getAbilityImage());
            map.put("title", "人才能力测评");
            map.put("content", "购买起" + ability.getExpireTime() + "天内有效");
            map.put("price", targetAmount);
            map.put("iosPrice", new BigDecimal(ability.getAbilityPrice()).multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP));
        }
        if (type.equals(3)) {//直播购买
            SysLive live = liveService.getById(targetId);
            targetAmount = live.getRegFee();
            if (applyType.equals(2)) {
                targetAmount = live.getRegFee().multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP);
            }
            map.put("img", live.getLiveImage());
            map.put("title", live.getLiveTitle());
            map.put("content", "直播时间：" + live.getLiveTime());
            map.put("price", targetAmount);
            map.put("iosPrice", live.getRegFee().multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP));
        }
        if (type.equals(5)) {//vip
            SysVipPrice vipPrice = vipPriceService.getById(targetId);
            SysVipType vip = vipTypeService.getById(vipPrice.getVipTypeId());
            targetAmount = vipPrice.getAndroidPrice();
            if (applyType.equals(2)) {
                targetAmount = vipPrice.getIosPrice();
            }
            map.put("img", vip.getVipImg());
            map.put("title", vip.getVipName());
            map.put("content", "购买起" + vipPrice.getVipTime() + "月内有效");
            map.put("price", targetAmount);
            //map.put("iosPrice", vip.getVipPrice().multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP));
            //map.put("iosPrice", vipPrice.getAmount());
        }
        if (type.equals(6)) {//线下课程
            SysOffCourse offcourse = offcourseService.getById(targetId);
            Date deadline = offcourse.getDeadline();//截至报名日期
            if (DateTime.now().isAfter(deadline)) {
                return ResultBody.failed("报名已截至");
            }
            if (ObjectUtils.isNotEmpty(offcourse.getApplyType())) {
                if (offcourse.getApplyType().equals(0)) {
                    return ResultBody.failed("报名未开始");
                }
                if (offcourse.getApplyType().equals(2)) {
                    return ResultBody.success("报名已结束");
                }
            }
            SysLecturer lecturer = lecturerService.getById(offcourse.getLecturerId());
            targetAmount = offcourse.getCoursePrice();
            if (applyType.equals(2)) {
                targetAmount = offcourse.getCoursePrice().multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP);
            }
            map.put("img", offcourse.getCourseImage());
            map.put("title", offcourse.getCourseTitle());
            if (ObjectUtils.isNotEmpty(lecturer)) {
                map.put("content", "讲师：" + lecturer.getLecturerName());
            } else {
                map.put("content", "");
            }
            map.put("price", targetAmount);
            map.put("iosPrice", offcourse.getCoursePrice().multiply(iosRatio).setScale(0, BigDecimal.ROUND_UP));
        }
        if (targetAmount.compareTo(balance.getAmount()) > 0) {
            map.put("needRecharge", 1);//需要充值
            map.put("shortAmount", targetAmount.subtract(balance.getAmount()));
        }
        return ResultBody.success(map);
    }

    /**
     * 苹果支付回调（临时）
     */
    @PostMapping("/pay_success_iap")
    public ResultBody pay_success_iap(String orderId) {
        Order order = bizService.getById(orderId);
        order.setPayType(PayTypeEnum.getEnum(PayTypeEnum.iap.code));
        return balanceService.pay_back(order);
    }

    /**
     * 提交发票
     */
    @PostMapping(value = "/addInvoice")
    public ResultBody addInvoice(SysInvoice invoice) {
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        Order order = bizService.getById(invoice.getOrderId());
        if (!OrderStatusEnum.finish.equals(order.getOrderStatus())) {
            return ResultBody.failed("该订单未完成无法申请发票");
        }
        if (order.getIsInvoice().equals(1)) {
            return ResultBody.failed("该订单已申请发票，无法重复申请");
        }
        invoice.setUserId(String.valueOf(openUserAuth.getUserId()));
        String fpqqlsh = GetInvoice.getInvoice(invoice, order.getId().toString());
        if (ObjectUtils.isEmpty(fpqqlsh)) {
            return ResultBody.failed("发票申请失败");
        }
        invoice.setInvoiceStatus(0);
        if(invoice.getEinvoice().equals("1")){
            invoice.setInvoiceStatus(1);
        }
        invoice.setFpqqlsh(fpqqlsh);
        boolean a = invoiceService.save(invoice);
        if (a) {
            order.setIsInvoice(1);
            bizService.saveOrUpdate(order);
            return ResultBody.ok("发票申请已提交，请耐心等待");
        }
        return ResultBody.failed("申请发票失败");
    }

    /**
     * 模糊查询
     */
    @PostMapping(value = "/selectCompany")
    public ResultBody selectCompany(String companyName) {
        String token = sysconfigService.getByName("nuoToken").getConfigVal();
        List<Map> map = GetInvoice.selectByName(companyName, token);
        return ResultBody.success(map);
    }

    /**
     * 根据企业开票码查询税号
     */
    @PostMapping(value = "/findByCompany")
    public ResultBody findByCompany(String kCode){
        String token = sysconfigService.getByName("nuoToken").getConfigVal();
        Map<String, Object> map = GetInvoice.selectByName2(kCode, token);
        Map<String, Object> kpMap = (Map<String, Object>) map.get("result");
        return ResultBody.success(kpMap);

    }


    /**nuoToken
     * 查询用户订单
     */
    @PostMapping(value = "/thirdorderList")
    public ResultBody thirdorderList(@ModelAttribute(value = "pagerInfo") PagerInfo pagerInfo, Order order) {
        OpenUserAuth openUserAuth = OpenHelper.getUserAuth();
        CriteriaQuery cq = new CriteriaQuery<EntityMap>(pagerInfo);
        EntityMap.setEnumConvertInterceptor(order);
        cq.select("o.id orderId,o.orderAmount,o.payType,o.orderBody courseTitle,o.orderImage courseImage," +
            "o.isInvoice,o.orderNo,o.orderStatus,o.createTime,o.payStatus,o.targetId,o.orderEntity,o.applyType," +
            "case when o.orderEntity = 'OT_TOP' then chargeconfig.iosId when o.orderEntity = 'OT_VIP' then vipprice.iosId else '0' end iosId");
        cq.eq("userId", openUserAuth.getUserId());
        if (ObjectUtils.isNotEmpty(order.getOrderStatus())) {
            cq.eq("orderStatus", order.getOrderStatus().code);
        }
        cq.eq("isDel", 2);
        cq.orderByDesc("o.createTime");
        cq.createAlias("vipprice", "vipprice");
        cq.createAlias("chargeconfig", "chargeconfig");
        PqGrid pqGrid = bizService.pageList(cq);
        //将用户所有的未读订单消息改为已读
        messageSendService.updateByUser(openUserAuth.getUserId(),2);
        return ResultBody.success(pqGrid);
    }


}
